前端下载普通文件与二进制流文件 您所在的位置:网站首页 js File对象转二进制文件流 前端下载普通文件与二进制流文件

前端下载普通文件与二进制流文件

2023-12-08 23:41| 来源: 网络整理| 查看: 265

前端下载文件通常会遇到这样两种情况

文件上传到资源服务器上,后端只保存了文件地址,前端拿到后端返回的文件地址直接下载。 文件就存在后端服务器上(通常是临时根据前端参数动态生成,用完就删除),后端读取文件后向前端返回文件的二进制流。

下面以下载excel文件为例,分别模拟展示这两种情况。(前置准备:vscode,node8+,vue-cli3.5+)。

一、 通过文件地址直接下载

在空目录test下新建service目录模拟后端,新建index.html文件模拟前端。

在service目录中新建一个excel文件 test.xlsx用于下载。

安装serve用来启动静态资源服务器

npm install -g serve

进入service目录,启动服务

cd service serve -s

此时这个test文件的地址就是:http://localhost:5000/test.xlsx

在页面中放一个a标签,href中写上文件的路径,并写上download属性。

点击下载

在浏览器中打开index.html,点击下载。

这种下载相当于一个get请求,浏览器直接访问该静态资源地址,download属性告诉浏览器这个a标签不是打开页面预览而是进行下载。

这与通常在实际项目中通过ajax请求接口无关,只需要照常请求,因为后端返回的只是文件的地址,拿到地址后绑定在a标签中或者通过window.open()都可以进行下载,不再单独在项目中进行演示。

二、二进制流文件下载

这种情况一般就是实际项目使用的ajax请求接口方式,比如post请求,前端传递若干参数,后端返回文件二进制流。

删除index.html,返回test目录下,使用vue-cli创建一个vue项目。

cd ../ vue create demo

选择最简单的default模板,创建好后进入项目目录安装axios,最后启动。

cd demo npm i axios --save npm run serve

删除src/App.vue中的多余内容,添加一个下载按钮。

在service目录中创建service.js写一个下载的接口。

关于跨域cors设置参考:juejin.cn/post/684490…

const http = require("http"); const fs = require("fs"); // 创建服务 const server = http.createServer((req,res) => { // 下载接口 if(req.url === "/download") { res.writeHead(200, { "Content-type": "application/vnd.ms-excel", // 返回excel文件 // 跨域设置 "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "content-type" }) // 异步读取文件内容 fs.readFile("test.xlsx", (err, data) => { // 返回二进制流文件 res.end(data) }) } }) // 服务启动在3000端口 server.listen(3000) console.log("server run at 3000")

在service目录下新开一个终端窗口,启动后端服务。

node service.js

回到App.vue,给下载按钮添加点击事件。

handleDownload() { axios({ method: 'post', url: "http://localhost:3000/download", data: { test: "test data" } }).then(response => { console.log(response.data) }) },

此时点击下载,可以看到返回的结果是乱码。

其实根本原理跟上面普通下载一样,都是通过一个文件的地址去下载,所以现在关键就是现在把这些二进制数据生成一个文件url。

首先设置axios配置项返回结果为二进制格式。

axios({ method: 'post', url: "http://localhost:3000/download", data: { test: "test data" }, responseType: "arraybuffer" // arraybuffer是js中提供处理二进制的接口 })

拿到返回数据后,将二进制数据生成一个文件url,用URL.createObjectURL生成url时需要传入Blob类型的参数。

关于Blob类型:juejin.cn/post/684490…

生成了url后就是模拟a标签来下载。

.then(response => { // 用返回二进制数据创建一个Blob实例 let blob = new Blob([response.data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }) // for .xlsx files // 通过URL.createObjectURL生成文件路径 let url = window.URL.createObjectURL(blob) // 创建a标签 let ele = document.createElement("a") ele.style.display = 'none' // 设置href属性为文件路径,download属性可以设置文件名称 ele.href = url ele.download = "测试文件" // 将a标签添加到页面并模拟点击 document.querySelectorAll("body")[0].appendChild(ele) ele.click() // 移除a标签 ele.remove() });

回到浏览器点击下载,这次二进制流文件下载成功。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有